<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <base data-ice="baseUrl" href="../../../">
  <title data-ice="title">lib/type/index.js | API Document</title>
  <link type="text/css" rel="stylesheet" href="css/style.css">
  <link type="text/css" rel="stylesheet" href="css/prettify-tomorrow.css">
  <script src="script/prettify/prettify.js"></script>
  
  
  <script src="script/manual.js"></script>
</head>
<body class="layout-container" data-ice="rootContainer">

<header>
  <a href="./">Home</a>
  
  <a href="identifiers.html">Reference</a>
  <a href="source.html">Source</a>
  
  <a data-ice="repoURL" href="https://git.oschina.net/kinuxroot/unique-model.js.git">Repository</a>
  <div class="search-box">
  <span>
    <img src="./image/search.png">
    <span class="search-input-edge"></span><input class="search-input"><span class="search-input-edge"></span>
  </span>
    <ul class="search-result"></ul>
  </div>
</header>

<nav class="navigation" data-ice="nav"><div>
  <ul>
    
  <li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/lib/session.js~Session.html">Session</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-createSession">createSession</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-enablePersist">enablePersist</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-isPersistEnabled">isPersistEnabled</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-variable">V</span><span data-ice="name"><span><a href="variable/index.html#static-variable-BaseModel">BaseModel</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-variable">V</span><span data-ice="name"><span><a href="variable/index.html#static-variable-Types">Types</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-variable">V</span><span data-ice="name"><span><a href="variable/index.html#static-variable-model">model</a></span></span></li>
<li data-ice="doc"><div data-ice="dirPath" class="nav-dir-path">backend</div><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/lib/backend/base.js~Dao.html">Dao</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/lib/backend/base.js~Session.html">Session</a></span></span></li>
<li data-ice="doc"><div data-ice="dirPath" class="nav-dir-path">model</div><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/lib/model/base.js~Model.html">Model</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-createModel">createModel</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-getModel">getModel</a></span></span></li>
<li data-ice="doc"><div data-ice="dirPath" class="nav-dir-path">type</div><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/lib/type/index.js~BaseType.html">BaseType</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/lib/type/index.js~Double.html">Double</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/lib/type/index.js~Integer.html">Integer</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/lib/type/index.js~Text.html">Text</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/lib/type/index.js~UObject.html">UObject</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-defineType">defineType</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-toUniqueModel">toUniqueModel</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-variable">V</span><span data-ice="name"><span><a href="variable/index.html#static-variable-allTypes">allTypes</a></span></span></li>
</ul>
</div>
</nav>

<div class="content" data-ice="content"><h1 data-ice="title">lib/type/index.js</h1>
<pre class="source-code line-number raw-source-code"><code class="prettyprint linenums" data-ice="content">&apos;use strict&apos;

/**
 * Unqiue model object.
 *
 * @private
 * @type {Object}
 */
let um = {
    model: require(&apos;../model&apos;)
};

/**
 * The base class of all types.
 *
 * @public
 */
class BaseType {
    /**
     * The constructor of class.
     *
     * @public
     * @param {String} [name] - The name of type.
     */
    constructor(name) {
        this._name = name;
    }

    /**
     * Get the name of type.
     *
     * @public
     * @type {String}
     */
    get name() {
        return this._name;
    }

    /**
     * Set the name of type.
     *
     * @public
     * @type {String}
     */
    set name(name) {
        this._name = name;
    }

    /**
     * Convert the JavaScript value to the standard type of the model type.
     * It will call _fromValue to complete the task.
     *
     * @public
     *
     * @param {?*} [value] - The value of data
     *
     * @return {*} The value which is the standard type of model type. Return null if value is null.
     *
     * @example 
     *  let data = {
     *      name: &apos;test&apos;,
     *      password: &apos;123&apos;
     *  }; 
     *
     *  let model = type.fromValue(data);
     */
    fromValue(value) {
        if ( value === null ) {
            return null;
        }
        if ( value === undefined ) {
            return null;
        }

        return this._fromValue(value);
    }
    
    /**
     * Convert the JavaScript value to the standard type of the model type.
     * It is called by fromValue.
     * You muse implement the method in your own type.
     *
     * @protected
     * @abstract
     *
     * @param {!*} [value] - The value of data
     *
     * @return {Any type} The value which is the standard type of model type.
     */
    _fromValue(value) {
        return null;
    }
}

/**
 * The field type of integer.
 * It use Number to represent the value.
 *
 * @public
 */
class Integer extends BaseType {
    /**
     * The constructor of class.
     *
     * @public
     * @param {Object} [options] - The options of type.
     */
    constructor(options) {
        super(&apos;Integer&apos;);
    }

    /**
     * Convert the value to integer.
     * The type of value is Number.
     * If the value is decimal fraction, it will truncate it into integer.
     *
     * @protected
     * @override
     *
     * @param {!*} [value] - The value of data
     *
     * @return {Number} The integer value
     */
    _fromValue(value) {
        return Math.trunc(Number(value));
    }
}

/**
 * The field type of double.
 * It use Number to represent the value.
 *
 * @public
 */
class Double extends BaseType {
    /**
     * The constructor of class.
     *
     * @public
     * @param {Object} [options] - The options of type.
     */
    constructor(options) {
        super(&apos;Double&apos;);
    }

    /**
     * Convert the value to double.
     * The type of value is Number.
     *
     * @protected
     * @override
     *
     * @param {!*} [value] - The value of data
     *
     * @return {Number} The double value
     */
    _fromValue(value) {
        return Number(value);
    }
}

/**
 * The field type of text.
 * It use String to represent the value.
 *
 * @public
 */
class Text extends BaseType {
    /**
     * The constructor of class.
     *
     * @public
     * @param {Object} [options] - The options of type.
     */
    constructor(options) {
        super(&apos;Text&apos;);
    }

    /**
     * Convert the value to text.
     * The type of value is String.
     *
     * @protected
     * @override
     *
     * @param {!*} [value] - The value of data
     *
     * @return {String} The string value
     */
    _fromValue(value) {
        return String(value);
    }
}

/**
 * The field type of unique object.
 * It use UniqueModel to represent the value.
 *
 * @public
 */
class UObject extends BaseType {
    /**
     * The constructor of class.
     *
     * @public
     * @param {Object} [options] - The options of type.
     * @param {String} [options.type] - The type model name of object.
     */
    constructor(options) {
        super(&apos;UObject&apos;);

        if ( &apos;type&apos; in options) {
            /**
             * The type of object(the unique model name).
             *
             * @type {String}
             */
            this.type = options.type;
        }
        else {
            throw &apos;You must specify the type of object&apos;;
        }
    }

    /**
     * Convert the value to unique object.
     * The type of value is UniqueModel.
     *
     * @protected
     * @override
     *
     * @param {!Object} [value] - The value of data.
     *
     * @return {model/base/Model} The UniqueModel object coresponding to value.
     */
    _fromValue(value) {
        let model = um.model.getModel(this.type);
        
        let uniqueModel = toUniqueModel(model, value);
        uniqueModel.id = value.id;

        return uniqueModel;
    }
}

/*
 * @private
 */
let allTypes = {
    Integer,
    Double,
    Text,
    UObject
};

/**
 * Convert the JavaScript object to unique object.
 * If you pass a UniqueModel object, it will replace the attributes in the object.
 * Or the function will create a new UniqueModel object.
 *
 * @public
 *
 * @param {class&lt;model/base/Model&gt;} [uniqueModel] - The UniqueModel type.
 * @param {Object} [objectToCopy] - The JavaScript object.
 * @param {model/base/Model} [uniqueModelObject] - The UniqueModel object.
 *
 * @return {model/base/Model} The UniqueModel object.
 */
function toUniqueModel(uniqueModel, objectToCopy, uniqueModelObject) {
    let schema = uniqueModel._meta.schema;

    if ( !uniqueModelObject ) {
        uniqueModelObject = new uniqueModel();
    }

    for ( let fieldName in schema ) {
        let fieldType = schema[fieldName];

        let fieldValue = objectToCopy[fieldName];
        uniqueModelObject[fieldName] = fieldType.fromValue(fieldValue);
    }
    uniqueModelObject.id = objectToCopy._id;

    return uniqueModelObject;
}

/**
 * Generate the function to define type.
 *
 * @public
 *
 * @param {String} [name] - The name of type.
 *
 * @return {function(name: String, options: Object): BaseType} The function to create type object.
 */
function defineType(name) {
    let executor = function(name, options) {
        let typeClass = allTypes[name];
        let type = new typeClass(options);

        return type;
    }

    return executor.bind(null, name);
}

module.exports = {
    Integer: defineType(&apos;Integer&apos;),
    Double: defineType(&apos;Double&apos;),
    Text: defineType(&apos;Text&apos;),
    UObject: defineType(&apos;UObject&apos;),
    toUniqueModel
};
</code></pre>

</div>

<footer class="footer">
  Generated by <a href="https://esdoc.org">ESDoc<span data-ice="esdocVersion">(0.4.3)</span></a>
</footer>

<script src="script/search_index.js"></script>
<script src="script/search.js"></script>
<script src="script/pretty-print.js"></script>
<script src="script/inherited-summary.js"></script>
<script src="script/test-summary.js"></script>
<script src="script/inner-link.js"></script>
<script src="script/patch-for-local.js"></script>
</body>
</html>
